external initialize: unit -> unit = "caml_Pm_Initialize"
external terminate: unit -> unit = "caml_Pm_Terminate"

type device_id = int
type device_info = {
	interf: string;
	name: string;
	input: bool;
	output: bool;
}
external count_devices: unit -> int = "caml_Pm_CountDevices"
external get_default_input_device_id: unit -> device_id = "caml_Pm_GetDefaultInputDeviceID"
external get_default_output_device_id: unit -> device_id = "caml_Pm_GetDefaultOutputDeviceID"
external get_device_info: device_id -> device_info = "caml_Pm_GetDeviceInfo"

type stream
type timestamp = int
external open_input_simple: device_id -> int -> stream = "caml_Pm_OpenInput_Simple"
external open_input: device_id -> int -> ('a -> int) -> 'a -> stream = "caml_Pm_OpenInput"
external open_output_simple: device_id -> int -> int -> stream = "caml_Pm_OpenOutput_Simple"
external open_output: device_id -> int -> ('a -> int) -> 'a -> int -> stream = "caml_Pm_OpenOutput"
external has_host_error: stream -> bool = "caml_Pm_HasHostError"
external abort: stream -> unit = "caml_Pm_Abort"
external close: stream -> unit = "caml_Pm_Close"

let filt_active = 1
let filt_sysex = 2
let filt_clock = 4
external set_filter: stream -> int -> unit = "caml_Pm_SetFilter"

type message = string
let message status data1 data2 =
	let message = String.create 4 in
	message.[0] <- char_of_int status;
	message.[1] <- char_of_int data1;
	message.[2] <- char_of_int data2;
	message.[3] <- '\000';
	message
let message_status message = int_of_char message.[0]
let message_data1 message = int_of_char message.[1]
let message_data2 message = int_of_char message.[2]

type event = { message: message; timestamp: timestamp }
external read: stream -> int -> event list = "caml_Pm_Read"
external poll: stream -> bool = "caml_Pm_Poll"
external write: stream -> event list -> unit = "caml_Pm_Write"
external write_short: stream -> timestamp -> message -> unit = "caml_Pm_WriteShort"
external write_sysex: stream -> timestamp -> string -> unit = "caml_Pm_WriteSysEx"
